package dao

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"go-admin/base/utils"
	"strings"
)

var _ UserModel = (*customUserModel)(nil)

type (
	// UserModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserModel.
	UserModel interface {
		userModel
		FindOneByUserNum(ctx context.Context, userNum string) (*User, error)
		FindAll(ctx context.Context) ([]*User, error)
		FindByUserIds(ctx context.Context, userIds []int64) ([]*User, error)
		DeleteByUserIds(ctx context.Context, userIds []int64) error
	}

	customUserModel struct {
		*defaultUserModel
	}
)

func (c customUserModel) DeleteByUserIds(ctx context.Context, userIds []int64) error {
	query := fmt.Sprintf("delete from %s where `id` in ( %s )", c.table, strings.Join(utils.GeneratePlaceholderByInt64(userIds), ","))
	_, err := c.conn.ExecCtx(ctx, query, utils.ConvertToAny(userIds)...)
	return err
}

func (c customUserModel) FindByUserIds(ctx context.Context, userIds []int64) ([]*User, error) {
	//query := fmt.Sprintf("select %s from %s where `id` in ( ? )", userRows, c.table)
	query := fmt.Sprintf("select %s from %s where `id` in ( %s )", userRows, c.table, strings.Join(utils.GeneratePlaceholderByInt64(userIds), ","))
	var resp []*User
	err := c.conn.QueryRowsCtx(ctx, &resp, query, utils.ConvertToAny(userIds)...)
	switch err {
	case nil:
		return resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

func (c customUserModel) FindAll(ctx context.Context) ([]*User, error) {
	query := fmt.Sprintf("select %s from %s ", userRows, c.table)
	var resp []*User
	err := c.conn.QueryRowsCtx(ctx, &resp, query)
	switch err {
	case nil:
		return resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

func (c customUserModel) FindOneByUserNum(ctx context.Context, userNum string) (*User, error) {
	query := fmt.Sprintf("select %s from %s where `user_num` = ? limit 1", userRows, c.table)
	var resp User
	err := c.conn.QueryRowCtx(ctx, &resp, query, userNum)
	switch err {
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

// NewUserModel returns a model for the database table.
func NewUserModel(conn sqlx.SqlConn) UserModel {
	return &customUserModel{
		defaultUserModel: newUserModel(conn),
	}
}
